package ru.dc.object.commands;

import java.util.Random;

/**
<h3>Syntax</h3> 
<pre>
 $Direction &lt;direction> &lt;number>|
 </pre>

<h3>Description</h3>

<p>This command is sent as a response to $Key. It decides which party gets to download.</p>

 <ul>
<li><direction> is either "Upload" or "Download", the only reason to say "Upload" would be that your client
 does not want to download anything from your peer.</li>
<li><number> is a random number, when both clients want to download, the one with the higher number starts first.
 if the numbers are equal, the connection is closed.</li>
</ul>

<h3>Peculiarities</h3>

<p>The highest <number> DC++ sends is 0x7FFF, NMDC will disconnect if it recieves a higher number.</p>

<p>DC++ does not send this command immediately after $Lock when an EXTENDED lock is encountered. See the $Supports.</p>

<p>DC++ has a bug that occurs when:</p>
<ul>
<li>client A has 0 free slots, client B may have free slots</li>
<li>client B wants files from A, client A wants files from B</li>
</ul>
 
<p>If client A tries to get something from B and it loses the random number "battle", client B doesn't get a slot
 because slots are full, and the status bar keeps saying "Connecting...". A patch for this is given on the
 discussion page. It cheats it's way out of the situation by using a high random number after it has lost,
 and returns to normal random when it has won.</p>

 <a href="http://www.teamfair.info/wiki/index.php?title=$Direction">http://www.teamfair.info/wiki/index.php?title=$Direction</a>
 */
public class Direction extends Command {

    private Constants operation;
    private int random;


    @Override
    public String generateCommand() {
        generateRandom();
        return getActualCommandName()+" "+getOperation().getOperation()+" "+ getRandom();
    }

    @Override
    public String getActualCommandName() {
        return "$Direction";
    }

    @Override
    public void parseCommand() {
        int startOp = getActualCommandName().length()+1;
        int endOp = getCommand().indexOf(" ", startOp);

        String operation = getCommand().substring(startOp, endOp);
        if (operation.equals(Constants.DOWNLOAD.getOperation())) {
            setOperation(Constants.DOWNLOAD);
        }
        else {
            setOperation(Constants.UPLOAD);
        }

        random = new Integer(getCommand().substring(endOp+1));
    }

    public void setOperation(Constants operation) {
        this.operation = operation;
    }

    public Constants getOperation() {
        return operation;
    }

    public int getRandom() {
        return random;
    }

    private void generateRandom() {
        random = Math.abs(new Random().nextInt(0x7FFF));
    }

    public void setRandom(int random) {
        this.random = random;
    }

    public static enum Constants {
        UPLOAD("Upload"), DOWNLOAD("Download");

        private String operation;

        Constants(String operation) {
            this.operation = operation;
        }

        public String getOperation() {
            return operation;
        }
    }


}
